package com.supermarket.service;

import com.supermarket.entity.ArticleLike;
import com.supermarket.exception.ArticleException;
import com.supermarket.mapper.ArticleLikeMapper;
import com.supermarket.mapper.ArticleMapper;
import com.supermarket.common.RedisUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class ArticleLikeService {

    @Resource
    private ArticleLikeMapper articleLikeMapper;
    
    @Resource
    private ArticleMapper articleMapper;
    
    @Resource
    private RedisUtil redisUtil;
    
    // Redis缓存相关的Key前缀
    private static final String ARTICLE_LIKE_USER_KEY = "article:like:user:";
    private static final String ARTICLE_LIKE_COUNT_KEY = "article:like:count:";
    private static final int ARTICLE_LIKE_CACHE_SECONDS = 3600; // 点赞缓存默认1小时

    /**
     * 点赞文章
     *
     * @param articleId 文章ID
     * @param userId    用户ID
     * @return 点赞后的文章点赞数
     */
    @Transactional
    public int likeArticle(Integer articleId, Integer userId) {
        // 检查文章是否存在
        if (articleMapper.selectArticleById(articleId) == null) {
            throw new ArticleException("文章不存在");
        }
        
        // 查找现有点赞记录
        ArticleLike existingLike = articleLikeMapper.selectByArticleAndUser(articleId, userId);
        
        if (existingLike == null) {
            // 创建新的点赞记录
            ArticleLike articleLike = new ArticleLike();
            articleLike.setArticleId(articleId);
            articleLike.setUserId(userId);
            articleLike.setStatus("ACTIVE");
            articleLikeMapper.insertArticleLike(articleLike);
        } else if ("CANCELLED".equals(existingLike.getStatus())) {
            // 恢复已取消的点赞
            articleLikeMapper.updateArticleLikeStatus(existingLike.getId(), "ACTIVE");
        } else {
            // 已经点赞过，不需要操作
            return articleLikeMapper.countActiveByArticleId(articleId);
        }
        
        // 更新文章点赞数量
        articleMapper.incrementLikes(articleId);
        
        // 清除缓存
        clearArticleLikeCache(articleId, userId);
        
        // 返回最新的点赞数量
        return articleLikeMapper.countActiveByArticleId(articleId);
    }

    /**
     * 取消点赞
     *
     * @param articleId 文章ID
     * @param userId    用户ID
     * @return 取消点赞后的文章点赞数
     */
    @Transactional
    public int unlikeArticle(Integer articleId, Integer userId) {
        // 检查文章是否存在
        if (articleMapper.selectArticleById(articleId) == null) {
            throw new ArticleException("文章不存在");
        }
        
        // 查找现有点赞记录
        ArticleLike existingLike = articleLikeMapper.selectByArticleAndUser(articleId, userId);
        
        if (existingLike != null && "ACTIVE".equals(existingLike.getStatus())) {
            // 更新点赞状态为取消
            articleLikeMapper.updateArticleLikeStatus(existingLike.getId(), "CANCELLED");
            
            // 更新文章点赞数量
            articleMapper.decrementLikes(articleId);
            
            // 清除缓存
            clearArticleLikeCache(articleId, userId);
        }
        
        // 返回最新的点赞数量
        return articleLikeMapper.countActiveByArticleId(articleId);
    }

    /**
     * 检查用户是否点赞过文章
     *
     * @param articleId 文章ID
     * @param userId    用户ID
     * @return 是否点赞过
     */
    public boolean hasUserLikedArticle(Integer articleId, Integer userId) {
        String cacheKey = ARTICLE_LIKE_USER_KEY + userId + ":" + articleId;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (boolean) cached;
        }
        
        // 缓存未命中，查询数据库
        ArticleLike like = articleLikeMapper.selectByArticleAndUser(articleId, userId);
        boolean hasLiked = like != null && "ACTIVE".equals(like.getStatus());
        
        // 将结果存入缓存
        redisUtil.set(cacheKey, hasLiked, ARTICLE_LIKE_CACHE_SECONDS);
        
        return hasLiked;
    }

    /**
     * 获取用户点赞的所有文章
     *
     * @param userId 用户ID
     * @return 点赞记录列表
     */
    public List<ArticleLike> getUserLikedArticles(Integer userId) {
        String cacheKey = ARTICLE_LIKE_USER_KEY + userId + ":all";
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (List<ArticleLike>) cached;
        }
        
        // 缓存未命中，查询数据库
        List<ArticleLike> likes = articleLikeMapper.selectActiveByUserId(userId);
        
        // 将结果存入缓存
        if (likes != null && !likes.isEmpty()) {
            redisUtil.set(cacheKey, likes, ARTICLE_LIKE_CACHE_SECONDS);
        }
        
        return likes;
    }

    /**
     * 批量检查用户是否点赞过文章
     *
     * @param userId     用户ID
     * @param articleIds 文章ID列表
     * @return 用户点赞过的文章ID列表
     */
    public List<Integer> getUserLikedArticleIds(Integer userId, List<Integer> articleIds) {
        // 如果文章ID列表为空，直接返回空列表
        if (articleIds == null || articleIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 构建缓存键，包含用户ID和文章ID列表的哈希值，以便区分不同的文章ID组合
        String articleIdsStr = articleIds.stream()
                .sorted()
                .map(String::valueOf)
                .collect(Collectors.joining("-"));
        String cacheKey = ARTICLE_LIKE_USER_KEY + userId + ":batch:" + articleIdsStr.hashCode();
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (List<Integer>) cached;
        }
        
        // 缓存未命中，查询数据库
        List<Integer> likedIds = articleLikeMapper.selectUserLikedArticles(userId, articleIds);
        
        // 将结果存入缓存，设置较短的过期时间，因为点赞状态可能频繁变化
        redisUtil.set(cacheKey, likedIds, 300); // 5分钟缓存
        
        return likedIds;
    }

    /**
     * 获取文章的点赞数量
     *
     * @param articleId 文章ID
     * @return 点赞数量
     */
    public int getArticleLikeCount(Integer articleId) {
        String cacheKey = ARTICLE_LIKE_COUNT_KEY + articleId;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (int) cached;
        }
        
        // 缓存未命中，查询数据库
        int count = articleLikeMapper.countActiveByArticleId(articleId);
        
        // 将结果存入缓存
        redisUtil.set(cacheKey, count, ARTICLE_LIKE_CACHE_SECONDS);
        
        return count;
    }
    
    /**
     * 清除文章点赞相关缓存
     */
    private void clearArticleLikeCache(Integer articleId, Integer userId) {
        if (articleId != null) {
            // 清除文章点赞数缓存
            redisUtil.delete(ARTICLE_LIKE_COUNT_KEY + articleId);
        }
        
        if (userId != null) {
            // 清除用户与特定文章的点赞状态缓存
            if (articleId != null) {
                redisUtil.delete(ARTICLE_LIKE_USER_KEY + userId + ":" + articleId);
            }
            
            // 清除用户所有点赞文章缓存
            redisUtil.delete(ARTICLE_LIKE_USER_KEY + userId + ":all");
            
            // 清除批量查询缓存
            Set<String> batchKeys = redisUtil.keys(ARTICLE_LIKE_USER_KEY + userId + ":batch:*");
            if (batchKeys != null && !batchKeys.isEmpty()) {
                redisUtil.delete(batchKeys);
            }
        }
    }
} 